package cn.shengongying.service;

import cn.shengongying.anon.PayStrategy;
import cn.shengongying.enums.PayEnum;
import cn.shengongying.model.BossOrder;
import cn.shengongying.model.PayResult;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;

import java.util.EnumMap;
import java.util.Map;

/**
 * author: RXK
 * date: 2022/1/10 星期一
 * desc:
 */
@Service
public class PayFactory implements ApplicationContextAware, InitializingBean {

    private ApplicationContext applicationContext;

    private static final EnumMap<PayEnum, IPayStrategyService> STRATEGY_SERVICE_ENUM_MAP = new EnumMap<>(PayEnum.class);


    public PayResult pay(BossOrder bossOrder) throws Exception {
        PayEnum payEnum = PayEnum.type(bossOrder.getPayType());
        IPayStrategyService strategyService = STRATEGY_SERVICE_ENUM_MAP.get(payEnum);
        return strategyService.pay(bossOrder);
    }

    public void callback(PayEnum wechat, Map<String, String> callback) {
        STRATEGY_SERVICE_ENUM_MAP.get(wechat)
                .callback(callback);
    }


    @Override
    public void afterPropertiesSet() {
        String[] namesForAnnotation = applicationContext.getBeanNamesForAnnotation(PayStrategy.class);
        for (String beanName : namesForAnnotation) {
            IPayStrategyService strategyService = (IPayStrategyService) applicationContext.getBean(beanName);
            STRATEGY_SERVICE_ENUM_MAP.put(strategyService.supportType(),strategyService);
        }
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    public void refund(PayEnum wechat, BossOrder bossOrder) {
        STRATEGY_SERVICE_ENUM_MAP.get(wechat)
                .refund(bossOrder);
    }

    public void handleRefund(PayEnum wechat, Map<String, String> data) {
        STRATEGY_SERVICE_ENUM_MAP.get(wechat)
                .handleRefundCallback(data);
    }
}
